import { createElem } from '@gis/lib/utils/domUtils.js';

export class MapInfoWindow {
  constructor({ map, AMap = null }) {
    this.map = map;
    this.AMap = AMap;
    this.data = {};
    this.offset = { x: 0, y: 0 };
  }
  getInfoWindow(then = () => {}) {
    if (!(this.infoWindow instanceof (this.AMap ? this.AMap.InfoWindow : AMap.InfoWindow))) {
      const configData = {
        isCustom: true,
        zIndex: 100,
        offset: this.AMap ? new this.AMap.Pixel(0, 0) : new AMap.Pixel(0, 0),
      };
      this.infoWindow = this.AMap ? new this.AMap.InfoWindow(configData) : new AMap.InfoWindow(configData);
      this.initEvent();
    }
    return then(this.infoWindow);
  }
  initEvent() {
    this.infoWindow.on('open', () => {
      this.map.on('click', this.close, this);
      this.map.on('zoomend', this.zoomEnd, this);
      setTimeout(() => {
        typeof this.bindEvent === 'function' && this.bindEvent();
      }, 300);
    });
    this.infoWindow.on('close', () => {
      typeof this.unBindEvent === 'function' && this.unBindEvent();
      this.map.off('click', this.close, this);
      this.map.off('zoomend', this.zoomEnd, this);
    });
  }
  zoomEnd() {
    this.getInfoWindow((infoWindow) => {
      if (infoWindow.getIsOpen()) infoWindow.setOffset(this.getOffset());
    });
  }
  getHeaderElem() {
    const header = createElem('div', { class: 'map-custom-pop-header' });
    const title = createElem('div', { class: 'map-custom-pop-header-title', children: this.getTitle() });
    const close = createElem('div', { class: 'map-custom-pop-header-close', children: '×' });
    close.onclick = () => {
      this.close();
    };
    header.appendChild(title);
    header.appendChild(close);
    return header;
  }
  getBodyElem() {
    const body = createElem('div', { class: 'map-custom-pop-body' });
    const content = this.getContent();
    if (content && content.nodeType === 1) {
      body.appendChild(content);
    } else {
      body.innerHTML = content;
    }
    return body;
  }
  getFooterElem() {
    const foot = this.getFooter();
    if (foot) {
      const footer = createElem('div', { class: 'map-custom-pop-footer' });
      if (foot.nodeType === 1) {
        footer.appendChild(foot);
      } else {
        footer.innerHTML = foot;
      }
      return footer;
    }
  }
  createInfoWindow() {
    const pop = createElem('div', { class: 'map-custom-pop' });
    // header
    const header = this.getHeaderElem();
    if (header) pop.appendChild(header);
    // body
    const body = this.getBodyElem();
    if (body) pop.appendChild(body);
    // footer
    const footer = this.getFooterElem();
    if (footer) pop.appendChild(footer);
    return pop;
  }
  close() {
    this.getInfoWindow((infoWindow) => {
      if (infoWindow.getIsOpen()) {
        this.map.off('click', this.close, this);
        infoWindow.close();
      }
    });
  }
  open(option = {}) {
    let { position, offset, data } = option;
    if (typeof option.getPosition === 'function') {
      position = option.getPosition();
    }
    if (typeof option.getOffset === 'function') {
      offset = option.getOffset();
      offset = { x: 0, y: offset.y };
    }
    if (typeof option.getExtData === 'function') {
      data = option.getExtData();
    }
    this.offset = Object.assign({ x: 0, y: 0 }, offset);
    this.data = Object.assign({}, data);
    this.getInfoWindow((infoWindow) => {
      infoWindow.setContent(this.createInfoWindow());
      infoWindow.setOffset(this.getOffset());
      infoWindow.open(this.map, position);
    });
  }
  getData() {
    return Object.assign({}, this.data);
  }
  getOffset() {
    const { x, y } = this.offset;
    return this.AMap ? new this.AMap.Pixel(x, y * 1.1) : new AMap.Pixel(x, y * 1.1);
  }
  getTitle() {
    return this.data ? this.data.title || '' : '';
  }
  getContent() {
    return '';
  }
  getFooter() {
    return '';
  }
}
